#include "DAL.h"
#include "DALUtils.h"
#include "DALCache.h"
#include "DALFileAccess.h"

//ASSERTING THAT THE ENVIRONMENT IS UP AND RUNNING

int EntityTypeAndIDAssert(DALResult* DR, String EntityType, unsigned int ID)
{
	if (ID == 0)
	{
		DR->Message = ILLEGAL_ID;
		return 1;
	}

	if (GetEntityTypeIndex(EntityType) == -1)
	{
		DR->Message = NO_SUCH_ENTITY_TYPE;
		return 1;
	}

	DR->Message = SUCCESS;
	DR->Result.Bytes = 0;
	DR->Result.Data = 0;

	return 0;
}

DALResult CreateOrEditEntity(String EntityType, unsigned int ID, DataEntity DEntity)
{
	DALResult result;
	if (EntityTypeAndIDAssert(&result, EntityType, ID))
		return result;

	unsigned int typeIndex = GetEntityTypeIndex(EntityType);

	//Add/edit the data entity to the file system and the cache
	CreateOrEditEntityInFile(typeIndex, ID, DEntity);
	CreateOrEditEntityInCache(typeIndex, ID, DEntity);

	return result;
}

DALResult GetEntity(String EntityType, unsigned int ID)
{
	DALResult result;

	if (EntityTypeAndIDAssert(&result, EntityType, ID))
		return result;

	unsigned int typeIndex = GetEntityTypeIndex(EntityType);

	//The cache system gives the most up-to-date version of the entity
	CacheEntity ce = GetEntityInCache(typeIndex, ID);

	//If the cache system marked this entity for delete, it means it's deleted
	if (ce.CacheType == CACHE_DELETE)
	{
		result.Message = NO_SUCH_ENTITY;
		return result;
	}

	DataEntity de = ce.DataEntity;

	//If we have data, attach the entity to the DALResult and return it
	if (de.Data)
	{
		result.Result = de;
		return result;
	}

	//We didn't find the entity in the cache, so if it exists, it can only be found in the file system
	de = GetEntityInFile(typeIndex, ID);

	//If we found it in the file system, cache it and return it
	if (de.Data)
	{
		SetEntityInCache(typeIndex, ID, de);
		result.Result = de;
		return result;
	}

	//We didn't find the entity at all, return the appropriate message
	result.Message = NO_SUCH_ENTITY;

	return result;
}

//TODO: Implement
DALResult DeleteEntity(String EntityType, unsigned int ID)
{
	DALResult result;
	if (EntityTypeAndIDAssert(&result, EntityType, ID))
		return result;

	unsigned int typeIndex = GetEntityTypeIndex(EntityType);

	//Delete the data entity from the cache, if this function returns 0, it means the cache already marked this entity for delete, so we know the file system also marked this entity for delete
	//Otherwise we must also mark the entity for delete in the file system
	if (DeleteEntityInCache(typeIndex, ID))
		DeleteEntityInFile(typeIndex, ID);

	return result;
}